#ifndef F_CPU
#define F_CPU 1000000UL
#endif

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

#include "i2cmaster.h"
#include "uart.h"




#define USART_BUFFER_SIZE 128
#define INPUT_BUFFER_SIZE 128
#define I2C_BUFFER_SIZE 128
#define DELAY_MS 1000

unsigned char address;
unsigned char reg;

#define UART_BAUD_RATE 2400

char DEVICE_ADDR = 0b1001101;
char DATA_REGISTER = 0b0;
char i2c_data;


unsigned char i2c_check_addr(unsigned char dev_addr);
unsigned char i2c_read_byte (unsigned char dev_addr, unsigned char reg);
unsigned int str_to_hex(const char* str);
unsigned char str_to_bin(const char* str);
void execute(const char* command);


char usart_data[USART_BUFFER_SIZE];
char input_buffer[INPUT_BUFFER_SIZE];
unsigned char i2c_buffer[I2C_BUFFER_SIZE];

int main(void)
{
	unsigned int c;
	
	uart_init(UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU)); 

    sei();

    uart_puts("String stored in SRAM\n");
    
    /*
     * Transmit string from program memory to UART
     */
    //uart_puts_P("String stored in FLASH\n");
	
    for(;;)
    {
        c = uart_getc();
        if ( c & UART_NO_DATA )
        {

        }
        else
        {
            if ( c & UART_FRAME_ERROR )
            {
                uart_puts("UART Frame Error: ");
            }
            if ( c & UART_OVERRUN_ERROR )
            {
                uart_puts("UART Overrun Error: ");
            }
            if ( c & UART_BUFFER_OVERFLOW )
            {
                uart_puts("Buffer overflow error: ");
            }
            uart_putc((unsigned char)c);
			uart_putc('\n');
			//uart_puts("Gets\n");
        }
		
		//_delay_ms(DELAY_MS);
    }
}

// 0 if a device with such address exists, 1 if it does not exist
unsigned char i2c_check_addr(unsigned char dev_addr)
{
    return i2c_start((dev_addr << 1) + I2C_WRITE);
}

unsigned char i2c_read_byte(unsigned char dev_addr, unsigned char reg)
{
    unsigned char result;
        
    // start writing
    i2c_start((dev_addr << 1) + I2C_WRITE); // we're going to write
    i2c_write(reg); // selecting a register
    // stop writing
        
    // start reading
    i2c_rep_start((dev_addr << 1) + I2C_READ); // we're going to read
    result = i2c_readNak();
    i2c_stop();
    // stop reading
                
    return result;
}

unsigned char* i2c_read_bytes(unsigned char dev_addr, unsigned char reg, int bytes_qnt, unsigned char* buffer)
{
    // start writing
    i2c_start((dev_addr << 1) + I2C_WRITE); // we're going to write
    i2c_write(reg); // selecting a register
    // stop writing
        
    // start reading
    i2c_rep_start((dev_addr << 1) + I2C_READ); // we're going to read
	
	for (int i = 0; i < bytes_qnt - 1; i++)
	{
		buffer[i] = i2c_readAck();
	}		
	buffer[bytes_qnt - 1] = i2c_readNak();
	
    i2c_stop();
    // stop reading
                
    return buffer;
}

unsigned int str_to_hex(const char* str)
{
    unsigned int res = 0;
        
    sscanf(str, "%x", &res);
        
    return res;
}

unsigned char str_to_bin(const char* str)
{
	unsigned char r = 0;
	
    for (int i = 0; str[i] != '\0'; i++)
    {
        r = r * 2 + str[i] - '0';
    }
	
	return r;
}

void execute(const char* command)
{

}
